home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
keyb
/
fixpat12.zip
/
FIXPATH.C--
< prev
next >
Wrap
Text File
|
1994-04-08
|
6KB
|
179 lines
/*
NAME: FIXPATH.C--
DESCRIPTION: TSR that removes the trailing backslash in command line
AUTHOR: Jean-Marc Lasgouttes (Jean-Marc.Lasgouttes@inria.fr)
VERSION: 1.2
*/
// First, some compilation directives
? alignword FALSE
? parsecommandline TRUE
// Then, some useful definitions
? include "DOS.H--"
? include "STRING.H--"
? define OLD21_OFS 0x0000 // Offset where holding the address of the old handler
? define NEW21_OFS 0x0004 // Offset at which the interrupt routine resides
byte progname = "FIXPATH";
? define len_progname 8
byte usage = "Usage : FIXPATH [/U]\n\n"
" /U uninstalls FixPath\n$";
// Now, the serious things can begin
// Resident routine ///////////////////////////////////////////////////////
: void FIXPATH() // removes trailing backslash in the command line
{ // DS:BX points to the command line
$ MOV BX, DX
$ CMP DSBYTE[BX+2], 0x20; // test whether the first character is a space
$ JZ END;
$ INC BX;
LOOP:
$ INC BX;
$ CMP DSBYTE[BX], 0x0D; // test for end of input
$ JZ END;
$ CMP DSBYTE[BX], 0x20; // test for space
$ JZ LOOP2;
$ CMP DSBYTE[BX], 0x3A; // test for colon
$ JZ LOOP2;
$ CMP DSWORD[BX], 0x205C; // test for backslash plus space
$ JZ REPLACE;
$ CMP DSWORD[BX], 0x0D5C; // test for backslash plus carriage return
$ JNZ LOOP;
REPLACE:
$ MOV DSBYTE[BX], 0x20; // replace backslash with space
$ JMP LOOP;
LOOP2:
$ INC BX;
$ CMP DSBYTE[BX], 0x0D; // test for end of input
$ JNZ LOOP;
END:
}
word olddoshandle[2] = {0,0}; // Address of the old interrupt handler
interrupt doshandler() // this is called every time INT 0x21 is invoked
{
$ PUSHF;
$ CMP AH, 0x0A;
$ JZ DOFIX;
$ POPF;
$ JMP CSDWORD[OLD21_OFS];
DOFIX:
$ CALL CSDWORD[OLD21_OFS]; // call the old handler to do the edit work
$ PUSH BX; // save BX; it will be restored later
@FIXPATH(); // Do the real work
END:
$ POP BX; // Restore BX
}
word endofdoshandle=0; // used to compute the length of the interrupt routine
// Transient part of the program //////////////////////////////////////////
// The following functions could be included in a general library
word instcheck(word name, len) // installation check
{
AH = 0x52; //
$ INT 0x21; // Get the DOS data segment
BX -= 2; // in ES
ES = ESWORD[BX]; //
do{
$ CLD; //
SI = name; //
DI = 8; // Compare the name to 'name'
CX = len; //
$ REPZ //
$ CMPSB //
IF( ZEROFLAG ){
DX = ES+1;
AX = CS; // First make sure
IF( AX != DX ) // it is not ourself
IF( DX == ESWORD[1] ) // Does the block owns itself?
return(DX); // Returns true
}
ES = ES+ESWORD[3]+1; // Go to the next MCB
}while(ESBYTE[0] != 0x5A); // Loop until the last MCB
return(0); // Return false
}
? define ENV_OFS 0x002C // offset in the PSP that holds the env. segment
: void RELEASEENV()
{
ES = DSWORD[ENV_OFS];
AH = 0x49;
$ INT 0x21;
}
// More FixPath-specific functions
void installint () // install our interrupt routine
word seg;
{
@RELEASEENV();
seg = @GETMEM(#endofdoshandle - #olddoshandle - 1 / 16 + 1);
IF( seg == 0 )
@DOSWRITESTR("ERROR: environment size too small to install FixPath\n$");
ELSE{
ES = seg-1; // change the MCB of the block
ESWORD[1]=seg; // to tell DOS that it owns itself
COPYFAR(ES,0x08,DS,#progname,len_progname); // write the name in the MCB
GETINTVECT(#olddoshandle,0x21); // get old DOS interrupt handle
COPYFAR(seg,OLD21_OFS,CS,#olddoshandle,#endofdoshandle-#olddoshandle);
// copy the interrupt routine into the new segment
SETINTVECT( ,0x21,seg,NEW21_OFS); // attach to DOS interrupt
}
}
void uninstall(word seg) // remove FixPath from memory if possible
word currentint21[2];
{
GETINTVECT(#currentint21,0x21); // Get the current DOS interrupt address
IF( DSWORD[#currentint21] == NEW21_OFS ) // Is it the resident
IF( DSWORD[#currentint21+2] == seg ){ // FixPath?
ES=seg;
SETINTVECT( ,0x21,ESWORD[OLD21_OFS+2],ESWORD[OLD21_OFS]);
@FREEMEM(seg);
@DOSWRITESTR("FixPath successfully removed from memory.\n$");
return();
}
@DOSWRITESTR("ERROR: Unable to remove FixPath from memory.\n$");
}
main()
byte str[80];
{
@DOSWRITESTR("FixPath 1.2 by Jean-Marc Lasgouttes.\n$");
instcheck(#progname, len_progname);
DX = AX; // AX = instcheck(): 0 or the segment where FixPath is
AX = @PARAMCOUNT();
IF(AX==0)
IF( DX != 0 )
@DOSWRITESTR("ERROR: FixPath is already installed.\n$");
ELSE
installint();
ELSE{
strcpy(#str, @PARAMSTR(0));
@STR_UP(#str);
IF( @STRCMP(#str,"/U") )
@DOSWRITESTR(#usage);
ELSE
IF( DX != 0 )
uninstall(DX);
ELSE
@DOSWRITESTR("ERROR: FixPath is not installed.\n$");
}
} /* Terminate but don't stay resident. The interrupt routine is in the
environment segment. */
/* end of FIXPATH.C-- */